<template>
  <div class="cr-contianer">
    <div class="title">{{ label }}</div>
    <div style="height: 100%;position: relative;">
      <flexbox
        justify="flex-start"
        align="center"
        class="search-box">
        <div>搜索：</div>
        <el-input
          v-model="searchContent"
          :placeholder="requestConfig.placeholder || ''"
          class="search-container">
          <el-button
            slot="append"
            icon="el-icon-search"
            @click="handleToSearch"/>
        </el-input>
        <flexbox-item>
          <flexbox align="center" justify="flex-end">
            <slot name="header-right" />
          </flexbox>
        </flexbox-item>
      </flexbox>

      <el-table
        v-loading="loading"
        ref="multipleTable"
        :row-height="40"
        :data="tableData"
        :height="250"
        stripe
        border
        highlight-current-row
        style="width: 100%"
        @selection-change="handleSelectionChange">
        <el-table-column
          show-overflow-tooltip
          type="selection"
          align="center"
          width="55"/>
        <template v-for="(item, index) in tableFieldList">
          <el-table-column
            v-if="item.formType === 'pic'"
            :key="index"
            :label="item.name"
            :fixed="item.fixed"
            :prop="item.fieldName"
            width="112"
            header-align="left"
            align="center">
            <template slot-scope="scope">
              <template
                v-if="isArrayType(scope.row[scope.column.property])">
                <adapter-image
                  v-for="(valObj, valIndex) in scope.row[scope.column.property]"
                  :key="valIndex"
                  :src="valObj.url"
                  @click.stop="previewImage(scope, valIndex)" />
              </template>
              <template v-else>
                <adapter-image
                  :src="scope.row[scope.column.property]"
                  @click.stop="previewImage(scope, null)" />
              </template>
            </template>
          </el-table-column>
          <el-table-column
            v-else
            :key="index"
            :fixed="index === 0"
            :prop="item.fieldName"
            :label="item.name"
            :formatter="item.formatter || null"
            show-overflow-tooltip />
        </template>
        <el-table-column v-if="tableData.length === 0" />
      </el-table>

      <div
        v-if="page"
        class="table-footer">
        <el-button
          :disabled="currentPage <= 1"
          @click.native="changePage(-1)">上一页</el-button>
        <el-button
          :disabled="currentPage >= totalPage"
          @click.native="changePage(1)">下一页</el-button>
      </div>
    </div>
    <div class="handle-bar">
      <el-button @click="closeView">取消</el-button>
      <el-button
        type="primary"
        @click="confirmClick">确定</el-button>
    </div>
  </div>
</template>

<script type="text/javascript">
import { separator } from '@/filters/vueNumeralFilter/filters'
import AdapterImage from './AdapterImage'
import { objDeepCopy } from '@/utils'
import { isArray, isObject, isEmpty } from '@/utils/types'

export default {
  name: 'RelativeCard', // 相关
  components: {
    AdapterImage
  },
  props: {
    /**
     * 请求配置
     * {
     *   fieldRequest: Function 表头字段请求
     *   fieldParams: Object 表头字段请求参数
     *   fieldList: Array 表头字段（如果有值，则不会再发起表头字段请求）
     *   listRequest: Function 列表数据请求
     *   listParams: Object 列表数据请求参数（不包括 page limit 参数）
     *   searchParamsFn: Function(oldParams, keyword) 拼接搜索请求参数，必须返回一个Object
     *   placeholder: String
     * }
     */
    requestConfig: {
      type: Object,
      required: true
    },
    relativeType: {
      type: String,
      default: ''
    },
    // 标题
    label: {
      type: String,
      default: '关联项'
    },
    // table 数据源
    list: {
      type: Array,
      default: () => []
    },
    // 是否为单选
    radio: {
      type: Boolean,
      default: false
    },
    // 选中的列表
    defaultValue: {
      type: Array,
      default: () => []
    },
    // 表格列主键 eg: productId supplierId
    primaryKey: {
      type: String,
      required: true
    },
    // popover 状态
    value: {
      type: Boolean,
      default: false
    },
    // 是否启用分页
    page: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      searchContent: null,

      loading: false,
      tableData: [], // 表格数据
      tableFieldList: [], // 表头数据
      selectedItem: [], // 已经选中的项
      hideSelectedItem: [], // 隐藏的选择项
      currentPage: 1, // 当前页
      totalPage: 0 // 总页数

      // allSelectedList: {} // 分别记录每页选中的数据
    }
  },
  watch: {
    value() {
      if (this.value && this.tableData.length === 0) {
        this.getData()
      }
    },
    defaultValue: {
      handler(val) {
        this.hideSelectedItem = []
        this.$nextTick(() => {
          if (isArray) {
            // this.selectedItem = objDeepCopy(this.defaultValue)
            this.selectedItem = this.defaultValue
          } else {
            this.selectedItem = [this.defaultValue]
          }
          this.setSelectedRow()
        })
      },
      immediate: true,
      deep: true
    },
    requestConfig: {
      handler() {
        this.tableData = []
      },
      deep: true
    }
  },
  methods: {
    getData() {
      this.currentPage = 1
      if (this.tableFieldList.length === 0) {
        this.getFieldList()
      } else {
        this.getTableData()
      }
    },

    /**
     * 获取表头字段
     */
    getFieldList() {
      const fieldList = this.requestConfig.fieldList
      if (fieldList) {
        const list = objDeepCopy(fieldList)
        this.formatField(list)
        this.getTableData()
        return
      }
      const request = this.requestConfig.fieldRequest
      const params = this.requestConfig.fieldParams
      if (!request) return

      this.loading = true
      request(params).then(res => {
        this.loading = false
        this.formatField(res.data)
        this.getTableData()
      }).catch(() => {
        this.loading = false
      })
    },

    formatField(list) {
      list.forEach(field => {
        if (!field.formatter) {
          if ([
            'supplier_cause',
            'purchase_cause',
            'sale_cause',
            'customer'
          ].includes(field.formType)) {
            field.formatter = function(row, column, cellValue, index) {
              if (cellValue) {
                return cellValue.name
              }
              return '--'
            }
          } else if (this.relativeType === 'customer') {
            if (field.fieldName === 'dealStatus') {
              field.formatter = function(row, column, cellValue, index) {
                if (cellValue) {
                  return cellValue == 1 ? '已成交' : '未成交'
                }
                return '--'
              }
            } else if (field.fieldName === 'status') {
              field.formatter = function(row, column, cellValue, index) {
                if (cellValue) {
                  return cellValue == 2 ? '已锁定' : '未锁定'
                }
                return '--'
              }
            }
          } else if (field.formType === 'floatnumber') {
            field.formatter = function(row, column, cellValue, index) {
              return separator(cellValue || 0)
            }
          } else if (field.formType === 'file') {
            field.formatter = function(row, column, cellValue, index) {
              if (isArray(cellValue) && !isEmpty(cellValue)) {
                return cellValue.map(o => o.name).join(',')
              }
              return '--'
            }
          } else {
            field.formatter = function(row, column, cellValue, index) {
              if (isObject(cellValue) && cellValue.hasOwnProperty('name')) {
                return cellValue.name || '--'
              }
              return cellValue || '--'
            }
          }
        }
      })

      this.tableFieldList = list
    },

    getUrl(val) {
      if (!val) return ''
      if (Object.prototype.toString.call(val) === '[object Array]') {
        if (val.length > 0) return val[0]
        return ''
      } else {
        return val
      }
    },

    previewImage(scope, dataIndex = null) {
      let arr = []
      const field = scope.column.property
      if (isEmpty(scope.row[field])) return
      const nowUrl = dataIndex === null ? scope.row[field].url : scope.row[field][dataIndex].url
      this.tableData.forEach((item, i) => {
        if (item[field] instanceof Array) {
          arr = arr.concat(item[field])
        } else {
          arr.push(item[field])
        }
      })
      arr = arr.filter(o => !!o)
      const findIndex = arr.findIndex(o => o.url === nowUrl)
      this.$bus.emit('preview-image-bus', {
        index: findIndex,
        data: arr
      })
    },

    /**
     * 获取表格数据
     */
    getTableData(refreshField = false) {
      const request = this.requestConfig.listRequest
      let params = objDeepCopy(this.requestConfig.listParams)
      if (!request) return
      params = this.getSearchParams(params)

      if (this.tableFieldList.length === 0 || refreshField) {
        this.currentPage = 1
        // this.allSelectedList = {}
      }
      let pageParams = {}
      if (this.page) {
        pageParams = {
          page: this.currentPage,
          limit: 10
        }
      }

      this.loading = true
      request({
        ...params,
        ...pageParams
      }).then(res => {
        this.tableData = res.data.hasOwnProperty('list') ? res.data.list : res.data
        this.totalPage = res.data.hasOwnProperty('totalPage') ? res.data.totalPage : 1
        this.loading = false
        this.setSelectedRow()
        this.$emit('data-ok', res.data)
      }).catch(() => {
        this.loading = false
      })
    },

    /**
     * 搜索
     */
    handleToSearch() {
      this.getTableData()
    },

    /**
     * 拼接搜索参数
     */
    getSearchParams(params) {
      const fn = this.requestConfig.searchParamsFn || null
      if (fn && typeof fn === 'function') {
        return this.requestConfig.searchParamsFn(params, this.searchContent)
      }
      return params
    },

    /**
     * 翻页
     */
    changePage(step) {
      this.currentPage += step
      // if (this.allSelectedList[this.currentPage]) {
      //   this.selectedItem = this.allSelectedList[this.currentPage]
      // }
      this.getTableData()
    },

    /**
     * 勾选默认选中的项
     */
    setSelectedRow() {
      let valArr = this.selectedItem || []
      valArr = valArr.concat(this.hideSelectedItem)
      // console.log('valArr: ', valArr)
      if (!this.$refs.multipleTable) return
      this.$refs.multipleTable.clearSelection()
      const arr = []
      this.hideSelectedItem = []
      valArr.forEach(v => {
        const id = v[this.primaryKey] || v.id || v
        const findRes = this.tableData.find(o => {
          return o[this.primaryKey] == id
        })
        if (findRes) {
          arr.push(findRes)
        } else {
          this.hideSelectedItem.push(v)
        }
      })
      this.$nextTick(() => {
        arr.forEach(item => {
          this.$refs.multipleTable.toggleRowSelection(item, true)
        })
      })
    },

    /**
     * 选项发生变化
     */
    handleSelectionChange(val) {
      if (val.length === 0) {
        this.selectedItem = []
        // this.allSelectedList[this.currentPage] = []
        return
      }
      if (this.radio) {
        this.hideSelectedItem = []

        val.forEach((row, index) => {
          if (index !== val.length - 1) {
            this.$refs.multipleTable.toggleRowSelection(row, false)
          }
        })
        if (val.length === 0) {
          this.selectedItem = []
        } else {
          this.selectedItem = val.length === 1 ? val : [val[val.length - 1]]
        }
      } else {
        this.selectedItem = val
      }
      // this.allSelectedList[this.currentPage] = this.selectedItem
    },

    /**
     * 关闭操作
     */
    closeView() {
      this.$emit('close')
    },
    /**
     * 确定选择
     */
    confirmClick() {
      const res = this.selectedItem.concat(this.hideSelectedItem)
      this.$emit('confirm', {
        data: res,
        valData: res.map(o => o[this.primaryKey])
      })
    },

    /**
     * 是数组
     */
    isArrayType(obj) {
      return isArray(obj)
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .cr-contianer {
    height: 450px;
    position: relative;
    padding: 50px 0 50px 0;
    .title {
      padding: 0 20px;
      font-size: 16px;
      font-weight: 600;
      line-height: 50px;
      height: 50px;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      z-index: 3;
      border-bottom: 1px solid $xr-border-line-color;
    }

    .search-box {
      font-size: 13px;
      padding: 10px 20px;
      .search-container {
        width: 200px;
        margin: 0 20px;
      }
    }

    .table-footer {
      padding: 8px 20px;
    }

    .handle-bar {
      height: 50px;
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      z-index: 2;
      background-color: #f7f8fa;
      border-top: 1px solid $xr-border-line-color;
      button {
        float: right;
        margin-top: 10px;
        margin-right: 10px;
      }
    }
  }

  .product-pic {
    max-width: 80px;
    max-height: 100px;
    vertical-align: middle;
    margin: 8px auto;
  }
</style>
